<?php
// +----------------------------------------------------------------------
// | Author: derek <693472824@qq.com> <http://www.bloveambition.com/>
// +----------------------------------------------------------------------

namespace Blovex4\Controller;
use Think\Controller;
use Blovex4\Logic\AdminLogic;
use Common\Api\PageApi;

/**
 * 后台基本控制器
 * @author derek <693472824@qq.com>
 */
class BaseController extends Controller {

    /**
     * 后台控制器初始化
     * @author derek <693472824@qq.com>
     */
    protected function _initialize(){
        // 获取当前用户ID
        if(defined('UID')) return ;
        
        $admin_id = AdminLogic::is_login();
        
        if(empty($admin_id) || (!is_numeric($admin_id))){
            // 还没登录 跳转到登录页面
            $this->redirect('Public/login');
        }else{
            define('ADMIN_ID', $admin_id);
            define('IS_ADMIN', AdminLogic::is_admin());
        }

        api('Server/loadConfig');
        
        $errmsg = '403:禁止访问';
        
        if(IS_ADMIN){
            $priv_checked = true;
        }else{
            $priv_checked = false;
        }
        
        if($this->accessControl() !== false){
            
            $adminMenus  =   session('ADMIN_MENU_LIST.'.CONTROLLER_NAME);
            
            if(empty($adminMenus)){
                
                $adminMenuTree = session('ADMIN_MENU_TREE');
                
                if(empty($adminMenuTree)){
                    
                    //当前用户有操作权限的菜单列表
                    $menu_fields = 'menu_id, menu_name, menu_url, parent_id';
                    $menus = D('Menu', 'Logic')->getMenusByUID($admin_id, $menu_fields);
                    
                    $adminMenuTree = api('Util/list_to_tree', array($menus, 'menu_id', 'parent_id', '_child', '0'));
                    
                    session('ADMIN_MENU_LIST', $menus);
                    session('ADMIN_MENU_TREE', $adminMenuTree);
                }
                
                $menus = session('ADMIN_MENU_LIST');
                
                if(empty($menus)){          //当前用户无任何菜单权限
                    
                    $this->redirect('Public/logout');
                    
                }else{                      //有菜单权限
                    
                    $adminMenus['main_menu'] = $adminMenuTree;
                    
                    $currentMenu = M('Menu')->where(array('menu_url'=>array('like', CONTROLLER_NAME.'/index%')))->find();
                    
                    if($currentMenu && !IS_AJAX){       //当前菜单存在，且当前操作不是 ajax 请求
                    
                        $menuID = $currentMenu['menu_id'];
                    
                        //获取当前菜单的顶级菜单ID
                        $superID = api('Util/getSuperID', array($menus, 'menu_id', 'parent_id', $menuID, 0));
                    
                        $req_url = strtolower(CONTROLLER_NAME.'/index');
                    
                        foreach ($adminMenuTree as $key=>$val){
                    
                            if($val['menu_id'] == $superID){
                    
                                foreach ($val['_child'] as $k=>$v){
                    
                                    $auth = preg_replace('/\?.*$/U', '', $v['menu_url']);
                    
                                    //判断当前用户是否有权使用当前菜单
                                    if(stripos($auth, $req_url) !== false){
                                        $priv_checked = true;
                                        break;
                                    }
                                }
                    
                                //有权执行当前操作，计算页面显示菜单
                                if($priv_checked === true){
                    
                                    $adminMenus['_child'] = $val['_child'];
                                    $menuURL = '';
                    
                                }elseif(!empty($val['_child'])){          //无权执行当前操作时，显示当前菜单CONTROLLER_NAME的兄弟菜单
                    
                                    $firstMenu = current($val['_child']);
                    
                                    if($firstMenu){
                                        $menuURL = $firstMenu['menu_url'];
                                    }else{
                                        $menuURL = 'Public/logout';
                                    }
                                }
                                break;
                            }
                        }
                    
                        if(!empty($menuURL)){
                            $this->redirect($menuURL);
                        }
                    }
                }
            }
            
            $admin_name = session('admin_auth.admin_name');
            
            $this->assign('__MENU__', $adminMenus);
            $this->assign('ADMIN_NAME', $admin_name);
            $this->assign('ADMIN_ID', $admin_id);
            return;
        }
        
        //当前权限检测失败
        $this->error($errmsg);
    }

    /**
     * action访问控制
     * 判断当前控制器 或 IP 地址  是否允许访问
     * @return boolean|null  返回值必须使用 `===` 进行判断
     *
     *   返回 **false**, 不允许任何人访问(超管除外)
     *   返回 **null**, 需要继续执行节点权限检测决定是否允许访问
     * @author derek <693472824@qq.com>
     */
    final protected function accessControl(){
        $allow = C('ALLOW_VISIT');
        $deny  = C('DENY_VISIT');
        $allow_ip = C('ADMIN_ALLOW_IP');
        
        if(!IS_ADMIN){
            $check = strtolower(CONTROLLER_NAME.'/'.ACTION_NAME);
            //检查当前控制器是否允许访问
            if (!empty($deny) && in_array_case($check,$deny) ) {
                return false;
            }
            
            //检查IP地址是否允许访问
            if(!empty($allow_ip) && !in_array(get_client_ip(),explode(',',$allow_ip))){
                return false;
            }
            
            //检查当前控制器是否允许访问（公共访问控制器类，如 Index/index）
            if (!empty($allow) && in_array_case($check,$allow) ) {
                return true;
            }
            
        }else{
            return true;
        }
        
        return null;
    }
    
    /**
     * 通用分页列表数据集获取方法
     *
     *  可以通过url参数传递where条件,例如:  index.html?name=asdfasdfasdfddds
     *  可以通过url空值排序字段和方式,例如: index.html?_field=id&_order=asc
     *  可以通过url参数r指定每页数据条数,例如: index.html?r=5
     *
     * @param sting|Model  $model   模型名或模型实例
     * @param array        $where   where查询条件(优先级: $where>$_REQUEST>模型设定)
     * @param array|string $order   排序条件,传入null时使用sql默认排序或模型属性(优先级最高);
     *                              请求参数中如果指定了_order和_field则据此排序(优先级第二);
     *                              否则使用$order参数(如果$order参数,且模型也没有设定过order,则取主键降序);
     *
     * @param boolean      $field   单表模型用不到该参数,要用在多表join时为field()方法指定参数
     * @author derek <693472824@qq.com>
     *
     * @return array|false
     * 返回数据集
     */
    protected function lists ($model,$where=array(),$order='',$field=true){
        
        $options    =   array();
        $REQUEST    =   (array)I('request.');
        
        if(is_string($model)){
            $model  =   M($model);
        }
    
        $OPT        =   new \ReflectionProperty($model,'options');
        $OPT->setAccessible(true);
    
        $pk         =   $model->getPk();
        
        if($order===null){
            //order置空
        }else if ( isset($REQUEST['_order']) && isset($REQUEST['_field']) && in_array(strtolower($REQUEST['_order']),array('desc','asc')) ) {
            $options['order'] = '`'.$REQUEST['_field'].'` '.$REQUEST['_order'];
        }elseif( $order==='' && empty($options['order']) && !empty($pk) ){
            $options['order'] = $pk.' desc';
        }elseif($order){
            $options['order'] = $order;
        }
        
        unset($REQUEST['_order'],$REQUEST['_field']);
    
        if( !empty($where)){
            $options['where']   =   $where;
        }
        
        $options      =   array_merge( (array)$OPT->getValue($model), $options );
        $total        =   $model->where($options['where'])->count();
    
        if( isset($REQUEST['r']) ){
            $listRows = (int)$REQUEST['r'];
        }else{
            $listRows = C('LIST_ROWS') > 0 ? C('LIST_ROWS') : 8;
        }
        
        $page = new PageApi($total, $listRows, $REQUEST);
        
        if($total>$listRows){
            $page->setConfig('theme','%HEADER% %FIRST% %UP_PAGE% %LINK_PAGE% %DOWN_PAGE% %END%');
        }
        
        $p =$page->show();
        $this->assign('_page', $p? $p: '');
        $this->assign('_total',$total);
        $options['limit'] = $page->firstRow.','.$page->listRows;
    
        $model->setProperty('options',$options);
    
        return $model->field($field)->select();
    }

}
